#include <kutils.h>
#include "idt.h"
#include "display.h"

struct idt_entry
{
    u16int base_lo;
    u16int sel;
    u8int always0;
    u8int flags;
    u16int base_hi;
} __attribute__((packed));

struct idt_ptr
{
    u16int limit;
    u32int base;
} __attribute__((packed));

struct idt_entry idt[256];
struct idt_ptr idtp;

extern void idt_load(void);
extern void irq64(void);//for syscalls

void idt_set_gate(u8int num, u32int base, u16int sel, u8int flags)
{
   // base address
	idt[num].base_lo = (u16int)(base & 0xFFFF);
	idt[num].base_hi = (u16int)(base >> 16) & 0xFFFF;

	//segment selector and other flags
	idt[num].sel = sel;
	idt[num].always0 = 0;
	idt[num].flags = flags;
}

void idt_install(void)
{
#ifdef FLUIDIUM_DEBUG
	write_string("IDT: Init\n");
#endif
	/* Sets the special IDT pos32inter up, just like in 'gdt.c' */
	idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
	idtp.base = (u32int)&idt;
	memset(&idt, 0, sizeof(struct idt_entry) * 256);

	//syscall gate
	idt_set_gate(64, (unsigned)irq64, 0x08, 0x8E);

	idt_load();
}
